/*
 * $Id: stdlib.c,v 1.7 2007-08-16 10:35:09 baconevi Exp $
 */

#include <xp/bas/stdlib.h>
#include <xp/bas/string.h>

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4018)
#endif

int xp_digtoi (xp_char_t c, int base)
{
	if (c >= XP_CHAR('0') && c <= XP_CHAR('9')) {
		c = c - XP_CHAR('0');
	}
	else if (c >= XP_CHAR('A') && c <= XP_CHAR('Z')) {
		c = c - XP_CHAR('A') + 10;
	}
	else if (c >= XP_CHAR('a') && c <= XP_CHAR('z')) {
		c = c - XP_CHAR('a') + 10;
	}
	else return base;

	return (c < base)? c: base;
}

xp_size_t xp_bytetostr_upper (xp_byte_t byte,
	xp_char_t* buf, xp_size_t size, int base, xp_char_t fill)
{
	xp_char_t tmp[(xp_sizeof(xp_byte_t) * 8)];
	xp_char_t* p = tmp, * bp = buf, * be = buf + size - 1;

	if (base < 2 || base > 36 || size <= 0) return 0;

	do {
		xp_byte_t digit = byte % base;	
		if (digit < 10) *p++ = digit + XP_CHAR('0');
		else *p++ = digit + XP_CHAR('A') - 10;
		byte /= base;
	} while (byte > 0);

	if (fill != XP_CHAR('\0')) {
		while (size - 1 > p - tmp) {
			*bp++ = fill;
			size--;
		}
	}

	while (p > tmp && bp < be) *bp++ = *--p;
	*bp = XP_CHAR('\0');
	return bp - buf;
}

xp_size_t xp_bytetostr_lower (xp_byte_t byte, 
	xp_char_t* buf, xp_size_t size, int base, xp_char_t fill)
{
	xp_char_t tmp[(xp_sizeof(xp_byte_t) * 8) + 1];
	xp_char_t* p = tmp, * bp = buf, * be = buf + size - 1;

	if (base < 2 || base > 36 || size <= 0) return 0;

	do {
		xp_byte_t digit = byte % base;	
		if (digit < 10) *p++ = digit + XP_CHAR('0');
		else *p++ = digit + XP_CHAR('a') - 10;
		byte /= base;
	} while (byte > 0);
	
	if (fill != XP_CHAR('\0')) {
		while (size - 1 > p - tmp) {
			*bp++ = fill;
			size--;
		}
	}

	while (p > tmp && bp < be) *bp++ = *--p;
	*bp = XP_CHAR('\0');
	return bp - buf;
}

int xp_atoi (const xp_char_t* str)
{
	int v;
	XP_STRTOI (v, str, XP_NULL, 10);
	return v;
}

long xp_atol (const xp_char_t* str)
{
	long v;
	XP_STRTOI (v, str, XP_NULL, 10);
	return v;
}

xp_int_t xp_strtoint (const xp_char_t* str)
{
	xp_int_t v;
	XP_STRTOI (v, str, XP_NULL, 10);
	return v;
}

xp_long_t xp_strtolong (const xp_char_t* str)
{
	xp_long_t v;
	XP_STRTOI (v, str, XP_NULL, 10);
	return v;
}

xp_uint_t xp_strtouint (const xp_char_t* str)
{
	xp_uint_t v;
	XP_STRTOI (v, str, XP_NULL, 10);
	return v;
}

xp_ulong_t xp_strtoulong (const xp_char_t* str)
{
	xp_ulong_t v;
	XP_STRTOI (v, str, XP_NULL, 10);
	return v;
}

xp_real_t xp_strtoreal (const xp_char_t* str)
{
	/* TODO: implement this */
	return 0.0;
}
